/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.core.determination;

import com.inspur.edp.bef.api.action.determination.IDeterminationContext;
import com.inspur.edp.bef.api.be.IBEContext;
import com.inspur.edp.bef.api.be.IBENodeEntity;
import com.inspur.edp.bef.api.be.IBENodeEntityContext;
import com.inspur.edp.bef.api.lcp.BefContext;
import com.inspur.edp.bef.api.lcp.IStandardLcp;
import com.inspur.edp.bef.core.LcpUtil;
import com.inspur.edp.bef.core.be.BEContext;
import com.inspur.edp.bef.core.be.CoreBEContext;
import com.inspur.edp.bef.core.session.FuncSessionManager;
import com.inspur.edp.cef.api.message.BizMessage;
import com.inspur.edp.cef.api.message.IBizMessage;
import com.inspur.edp.cef.api.message.IMessageCollector;
import com.inspur.edp.cef.api.message.ISupportBizMessage;
import com.inspur.edp.cef.api.message.MessageLevel;
import com.inspur.edp.cef.api.message.MessageLocation;
import com.inspur.edp.cef.entity.changeset.IChangeDetail;
import com.inspur.edp.cef.entity.dependenceTemp.DataValidator;
import com.inspur.edp.cef.entity.entity.ICefData;
import com.inspur.edp.cef.entity.entity.IEntityData;
import com.inspur.edp.cef.spi.entity.resourceInfo.ModelResInfo;
import com.inspur.edp.cef.variable.api.data.IVariableData;
import java.util.Arrays;
import java.util.List;

// 触发业务determination实现时传给业务代码的上下文
public class DeterminationContext implements IDeterminationContext, ISupportBizMessage {
  public DeterminationContext(IBENodeEntityContext beContext) {
    DataValidator.checkForNullReference(beContext, "beContext");

    this.privateBEContext = beContext;
  }

  @Override
  public IBENodeEntity getBENodeEntity() {
    return (IBENodeEntity) getBEContext().getDataType();
  }

  private IBENodeEntityContext privateBEContext;

  @Override
  public final IBENodeEntityContext getBEContext() {
    return privateBEContext;
  }

  private IChangeDetail privateRootChange;

  @Override
  public final IChangeDetail getRootChange() {
    return privateRootChange;
  }

  public final void setRootChange(IChangeDetail value) {
    privateRootChange = value;
  }

  // public IDtmAssemblerFactory DtmFactory { get; internal set; }

  private IMessageCollector messageCollector;

  public IMessageCollector getMessageCollector() {
    return (messageCollector != null)
        ? messageCollector
        : (messageCollector = getRootContext().getResponse().messageCollector);
  }

  private BEContext getRootContext() {
    IBENodeEntityContext curr = getBEContext();
    while (curr.getParentContext() != null) {
      curr = curr.getParentContext();
    }
    return (BEContext) curr;
  }

  @Override
  public final IEntityData getCurrentData() {
    return getBEContext().getCurrentData();
  }

  @Override
  public final IEntityData getTransactionData() {
    return getBEContext().getTransactionData();
  }

  @Override
  public final IEntityData getOriginalData() {
    return getBEContext().getOriginalData();
  }

  @Override
  public final void addMessage(IBizMessage msg) {
    DataValidator.checkForNullReference(msg, "msg");
    getMessageCollector().addMessage(msg);
  }

  // internal string DataId { get; set; }

  @Override
  public String getNodeCode() {
    return getBEContext().getCode();
  }

  @Override
  public void setNodeCode(String value) {
    throw new RuntimeException();
  }

  @Override
  public IEntityData getCurrentEntityData() {
    return getCurrentData();
  }

  public final BefContext getBefContext() {
    return getRootContext().getSessionItem().getFuncSession().getBefContext();
  }

  @Override
  public final IBizMessage createMessageWithLocation(
      MessageLevel level, String msg, String... msgPars) {
    BizMessage rez = new BizMessage();
    rez.setMessageFormat(msg);
    rez.setMessageParams(msgPars);
    rez.setLevel(level);
    rez.setLocation(new MessageLocation() {{
      setDataIds(Arrays.asList(getBEContext().getID()));
      setNodeCode(getBEContext().getCode());
    }});
    return rez;
  }

  @Override
  public final IBizMessage createMessageWithLocation(
      MessageLevel level, List<String> columnNames, String msg, String... msgPars) {
    IBizMessage rez = createMessageWithLocation(level, msg, msgPars);
    rez.getLocation().setColumnNames(columnNames);
    return rez;
  }

  @Override
  public final IStandardLcp getLcp(String configId) {
    return LcpUtil.getLcp(configId);
  }

  /** 变量, 只读数据不允许修改 */
   public IVariableData getVariables(){
     if(getBEContext()==null)
       return null;
     return getRootBEContext(getBEContext()).getVariables();
   }


  public static CoreBEContext getRootBEContext(IBENodeEntityContext context)
  {
    if(context.getParentContext()!=null) {
      while (context.getParentContext()!=null)
        context = context.getParentContext();
    }
    return (CoreBEContext)context;
  }

  // region i18n
  @Override
  public ModelResInfo getModelResInfo() {
    return getBEContext().getModelResInfo();
  }

  @Override
  public final String getEntityI18nName() {
    return getBEContext().getEntityI18nName();
  }

  @Override
  public final String getPropertyI18nName(String labelID) {
    return getBEContext().getPropertyI18nName(labelID);
  }

  @Override
  public final String getRefPropertyI18nName(String labelID, String refLabelID) {
    return getBEContext().getRefPropertyI18nName(labelID, refLabelID);
  }

  @Override
  public final String getEnumValueI18nDisplayName(String labelID, String enumKey) {
    return getBEContext().getEnumValueI18nDisplayName(labelID, enumKey);
  }

  @Override
  public final String getUniqueConstraintMessage(String conCode) {
    return getBEContext().getUniqueConstraintMessage(conCode);
  }

  // endregion

  /**
   * 获取字段国际化翻译后的值
   *
   * @param nodeCode 节点编号
   * @param labelID 字段标签
   */
  public final String getPropertyI18nName(String nodeCode, String labelID) {
    return getBEContext()
        .getModelResInfo()
        .getCustomResource(nodeCode)
        .getPropertyDispalyName(labelID);
  }

  // public IStandardLcp getLcp(string config, bool newSession)
  // {
  //    return LcpUtil.getLcp(config,newSession);
  // }

  @Override
  public ICefData getData() {
    return getCurrentData();
  }

  @Override
  public String getConfigId() {
    return getRootContext().getBizEntity().getBEType();
  }
}
